import tkinter as tk
from tkinter import ttk, messagebox


class UnitConverter:
    def __init__(self, root):
        self.root = root
        self.root.title("像素(px)与磅(pt)转换工具")
        self.root.geometry("450x350")
        self.root.resizable(True, True)

        # 设置DPI默认值和转换方向
        self.dpi_var = tk.StringVar(value="96")
        self.direction_var = tk.StringVar(value="px_to_pt")

        self.create_widgets()

    def create_widgets(self):
        # 设置样式
        style = ttk.Style()
        style.configure("TFrame", padding=10)
        style.configure("TButton", padding=5)
        style.configure("TLabel", font=("Arial", 12))
        style.configure("Header.TLabel", font=("Arial", 16, "bold"))
        style.configure("Result.TLabel", font=("Arial", 14, "bold"))

        # 创建主框架
        main_frame = ttk.Frame(self.root, style="TFrame")
        main_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)

        # 标题
        header_label = ttk.Label(main_frame, text="像素(px)与磅(pt)转换工具", style="Header.TLabel")
        header_label.pack(pady=(0, 15))

        # 说明
        info_label = ttk.Label(main_frame, text="1 磅(pt) = 1/72 英寸 | 在标准显示器 (96 DPI) 上: 1 px = 0.75 pt",
                               justify=tk.CENTER, wraplength=400)
        info_label.pack(pady=(0, 10))

        # DPI设置
        dpi_frame = ttk.Frame(main_frame)
        dpi_frame.pack(fill=tk.X, pady=5)

        dpi_label = ttk.Label(dpi_frame, text="显示器DPI值: ")
        dpi_label.pack(side=tk.LEFT, padx=(0, 5))

        dpi_entry = ttk.Entry(dpi_frame, width=8, textvariable=self.dpi_var)
        dpi_entry.pack(side=tk.LEFT, padx=5)

        dpi_info = ttk.Label(dpi_frame, text="(标准为96, Mac通常为72)")
        dpi_info.pack(side=tk.LEFT, padx=5)

        # 转换方向选择
        direction_frame = ttk.Frame(main_frame)
        direction_frame.pack(fill=tk.X, pady=10)

        px_to_pt_radio = ttk.Radiobutton(direction_frame, text="像素(px) → 磅(pt)",
                                         variable=self.direction_var, value="px_to_pt",
                                         command=self.update_labels)
        px_to_pt_radio.pack(side=tk.LEFT, padx=(0, 20))

        pt_to_px_radio = ttk.Radiobutton(direction_frame, text="磅(pt) → 像素(px)",
                                         variable=self.direction_var, value="pt_to_px",
                                         command=self.update_labels)
        pt_to_px_radio.pack(side=tk.LEFT)

        # 输入框架
        self.input_frame = ttk.Frame(main_frame)
        self.input_frame.pack(fill=tk.X, pady=5)

        self.input_label = ttk.Label(self.input_frame, text="输入像素值 (px): ")
        self.input_label.pack(side=tk.LEFT, padx=(0, 5))

        self.value_entry = ttk.Entry(self.input_frame, width=15)
        self.value_entry.pack(side=tk.LEFT, padx=5)
        self.value_entry.focus()

        # 转换按钮
        self.convert_button = ttk.Button(main_frame, text="转换", command=self.convert)
        self.convert_button.pack(pady=15)

        # 结果标签
        self.result_label = ttk.Label(main_frame, text="", style="Result.TLabel")
        self.result_label.pack(pady=10)

        # 等价值展示
        self.equivalence_frame = ttk.LabelFrame(main_frame, text="等价值参考")
        self.equivalence_frame.pack(fill=tk.X, pady=10)

        self.equiv_label = ttk.Label(self.equivalence_frame, text="", justify=tk.LEFT)
        self.equiv_label.pack(padx=10, pady=5)

        # 绑定回车键到转换功能
        self.root.bind('<Return>', lambda event: self.convert())

    def update_labels(self):
        if self.direction_var.get() == "px_to_pt":
            self.input_label.config(text="输入像素值 (px): ")
            self.convert_button.config(text="转换为磅(pt)")
        else:
            self.input_label.config(text="输入磅值 (pt): ")
            self.convert_button.config(text="转换为像素(px)")

        # 清除之前的结果
        self.result_label.config(text="")
        self.equiv_label.config(text="")

    def convert(self):
        try:
            # 获取输入值和DPI
            input_value = float(self.value_entry.get())
            dpi = float(self.dpi_var.get())

            if dpi <= 0:
                messagebox.showerror("错误", "DPI值必须大于0")
                return

            # 根据DPI计算转换比例
            ratio = 72.0 / dpi

            if self.direction_var.get() == "px_to_pt":
                # 像素转磅
                result = input_value * ratio
                self.result_label.config(text=f"{input_value} px = {result:.2f} pt")

                # 显示等价值
                inch = input_value / dpi
                mm = inch * 25.4
                cm = mm / 10
                self.equiv_label.config(text=f"{input_value} px ≈ {inch:.4f} 英寸 ≈ {mm:.2f} 毫米 ≈ {cm:.2f} 厘米\n"
                                             f"1 px = {ratio:.4f} pt (在 {dpi} DPI下)")
            else:
                # 磅转像素
                result = input_value / ratio
                self.result_label.config(text=f"{input_value} pt = {result:.2f} px")

                # 显示等价值
                inch = input_value / 72.0
                mm = inch * 25.4
                cm = mm / 10
                self.equiv_label.config(text=f"{input_value} pt ≈ {inch:.4f} 英寸 ≈ {mm:.2f} 毫米 ≈ {cm:.2f} 厘米\n"
                                             f"1 pt = {1 / ratio:.4f} px (在 {dpi} DPI下)")

        except ValueError:
            messagebox.showerror("错误", "请输入有效的数字")


# 创建主窗口并启动应用
if __name__ == "__main__":
    root = tk.Tk()
    app = UnitConverter(root)
    root.mainloop()